(define-module (sudoku init))

(use-modules (srfi srfi-1)
             (sudoku solver)
             (sudoku board)
             (sudoku square)
             (sudoku utils))

(define-public (initial-board)
  (init-board (initial-board-string)))

(define-public (init-board s)
  (init-board-candidates
    (init-board-values (make-9x9-board)
                       (string->num-list s))))

;;; TODO: use compose here
(define (init-board-candidates board)
  (init-rows (init-cols (init-boxes board))))

(define (init-rows board)
  (init-group update-row board))

(define (init-cols board)
  (init-group update-col board))

(define (init-boxes board)
  (init-group update-box board))

(define (init-group update-proc board)
  (for-each (lambda (i)
              (update-proc board i))
            (iota 9))
  board)

(define (init-board-values board vals)
  (array-map! (board-array board)
              set-square-value (board-array board)
              (list->array 2 (rank1->rank2 vals))) 
  board)

(define (initial-board-string)
  ;;"900060820000208005000409060290100603060000070704006052070803000500607000026040008")
  ;; "002090060040001008070420003500000300001060500003000006100057040600900020020080100") ;; easy 
 ;; "000070605000004080200006070073000200500000004004000960080400003050200000706080000") ;; hard 
 "800000000003600000070090200050007000000045700000100030001000068008500010090000400") ;; most difficult 
;;  "010004060034080000000010000400001080250000030070900005000070000003040890060200050")
;; (display (init-board "010004060034080000000010000400001080250000030070900005000070000003040890060200050"))
